package com.ost.kautilya.modeling;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public class ModelSortedList<T> extends ArrayList<T> implements List<T> {
	public static interface ExtendedInspector {

		boolean extendedCheck(int ma, int dcl);

	}

	private static final long serialVersionUID = 1L;
	private final Map<T, Model> fmap = new Hashtable<T, Model>();
	private List<ExtendedInspector> insp = new ArrayList<ExtendedInspector>();

	public boolean addModelBasedItem(T item, Model model) {
		boolean result = super.add(item);
		if (result) {
			fmap.put(item, model);
			// sort for dependencies
			int fi = indexOf(item);
			while (fi > 0) {
				for (int ci = fi - 1; ci > -1; ci--) {
					T dc = get(ci);
					Model dm = fmap.get(dc);
					boolean isDep = false;
					for (int ma : model.getAttributes()) {
						OUTER: for (int dcl : dm.getClasses()) {
							if (isDep = dcl == ma)
								break;
							for (ExtendedInspector ins : insp) {
								if (isDep = ins.extendedCheck(ma, dcl))
									break OUTER;
							}
						}
						if (isDep)
							break;
					}
					if (isDep) {
						fi = 0;
						break;
					} else {
						Collections.swap(this, fi, ci);
						fi = ci;
					}
				}
			}
			return true;
		} else return false;
	}

	@Deprecated
	public void add(int index, T element) {
		throw new Error("Please use addModelBasedItem instead.");
	}

	@Deprecated
	public boolean add(T e) {
		throw new Error("Please use addModelBasedItem instead.");
	}

	public void addExtendedInspector(ExtendedInspector ins) {
		if (!insp.contains(ins))
			insp.add(ins);
	}
}
